#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <SDL.h>


#include "misc.h"
#include "sprite.h"
#include "ship.h"
#include "direction.h"
#include "map.h"
#include "view.h"
#include "anim.h"

SDL_Renderer *g_renderer = NULL;

extern View g_view;
extern Ship* g_select_ship;

int main(int argc, char const *argv[]) {
    int res = 0;
    res = SDL_Init(SDL_INIT_EVERYTHING);
    CheckRes("SDL_Init", res != 0);

    atexit(SDL_Quit);

    InitView();

    SDL_Window *win = SDL_CreateWindow("Ships",
            SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
            g_view.window.width, g_view.window.height, 0);
    /*
       0, 0, SDL_WINDOW_FULLSCREEN_DESKTOP);
       */
    CheckRes("SDL_CreateWindow", win == NULL);

    g_renderer = SDL_CreateRenderer(win, -1,
            SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
    CheckRes("SDL_CreateRenderer", g_renderer == NULL);

    //SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
    res = SDL_RenderSetLogicalSize(g_renderer, g_view.window.width, g_view.window.height);
    CheckRes("SDL_RenderSetLogicalSize", res != 0);

    InitSprites();

    InitMap(20, 20);
    //DumpMap();

    int quit = 0;
    SDL_SetRenderDrawColor(g_renderer, 0, 0, 196, 255);
    unsigned int lastTime = 0;
    unsigned int currentTime;
    int move_direction;

    Anim* anim = 0;

    while (!quit) {
        SDL_Event e;
        while (SDL_PollEvent(&e)) {
            switch (e.type) {
                case SDL_MOUSEMOTION:
                    GetMapPos(&g_view.mouse_select.x, &g_view.mouse_select.y, e.motion.x, e.motion.y);
                    break;
                case SDL_MOUSEBUTTONDOWN:
                    if (SelectShip(g_view.mouse_select.x, g_view.mouse_select.y)) {
                        ;
                    } else {
                        if (g_select_ship && (move_direction = CanMoveShip(g_select_ship, g_view.mouse_select.x, g_view.mouse_select.y) - 1) != -1) {
                            Anim* rotate = InitAnimRotateShip(g_select_ship, move_direction);
                            Anim* move = 0;
                            int i;
                            int x_start = g_select_ship->x;
                            int y_start = g_select_ship->y;
                            int x_end = g_view.mouse_select.x;
                            int y_end = g_view.mouse_select.y;
                            for (i = 1; i <= MAX(abs(x_start - x_end), abs(y_start - y_end)); ++i) {
                                Anim* move_step = InitAnimMoveShip(g_select_ship, move_direction, 0);
                                int x;
                                int y;
                                OffsetToCoords(&x, &y, x_start, y_start, move_direction, i);
                                printf("test %s [%d, %d] [%d, %d]\n", DirectionToStr(move_direction), x_start, y_start,  x, y);
                                Ship* another_ship = ShipOnMap(x, y);
                                if (another_ship) {
                                    printf("found another ship = %p\n", another_ship);
                                    Anim* rotate_another_ship = InitAnimRotateShip(another_ship, MinRotateDirectin(another_ship, move_direction));
                                    move_step = InitAnimSequence(rotate_another_ship, move_step);
                                }
                                if (move) {
                                    move = InitAnimSequence(move, move_step);
                                } else {
                                    move = move_step;
                                }
                            }
                            anim = InitAnimSequence(rotate, move);
                            //printf("move ship to [%d, %d]\n", g_view.mouse_select.x, g_view.mouse_select.y);
                        }
                    }
                    break;
                case SDL_KEYDOWN:
                    switch (e.key.keysym.sym) {
                        case SDLK_ESCAPE:
                            quit = 1;
                            break;
                        case SDLK_UP:
                            MoveView(0, -10);
                            break;
                        case SDLK_DOWN:
                            MoveView(0, 10);
                            break;
                        case SDLK_LEFT:
                            MoveView(-10, 0);
                            break;
                        case SDLK_RIGHT:
                            MoveView(10, 0);
                            break;
                    }
                    break;
                case SDL_QUIT:
                    quit = 1;
                    break;
            }
        }

        currentTime = SDL_GetTicks();
        /* do 50 FPS */
        if (currentTime < lastTime + 20) {
            SDL_Delay(currentTime - lastTime);
        }

        if (anim) {
            if (UpdateAnim(anim, currentTime - lastTime)) {
                DestroyAnim(&anim);
                assert(anim == 0);
            }
        }

        lastTime = currentTime;

        SDL_RenderClear(g_renderer);

        DrawView();

        SDL_RenderPresent(g_renderer);
    }

    DestroyMap();
    DestroySprites();
    SDL_DestroyRenderer(g_renderer);
    SDL_DestroyWindow(win);
    SDL_Quit();

    return 0;
}
